﻿using OfficeClip.OpenSource.StyleFix.Drivers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using OfficeClip.OpenSource.StyleFix;
using System.Collections.Generic;

namespace StyleFixUnitTest
{


    /// <summary>
    ///This is a test class for ReadabilityRulesTest and is intended
    ///to contain all ReadabilityRulesTest Unit Tests
    ///</summary>
    [TestClass()]
    public class ReadabilityRulesTest
    {
        private TestContext testContextInstance;
        private ReadabilityRules target;
        private SAObject saObject;
        private List<SAObject> saObjects;


        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        public ReadabilityRulesTest()
        {
            target = new ReadabilityRules();
            target.ForceAllow = true;
            saObject = new SAObject(string.Empty, 1, 1, string.Empty, false);
        }

        /// <summary>
        ///A test for SA1101_PrefixLocalCallsWithThis
        ///</summary>
        [TestMethod()]
        public void SA1101_PrefixLocalCallsWithThisTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1101";
            saObject.Description = "The call to xyz must...";
            saObject.Column = 5;
            saObjects.Add(saObject);
            // no space before and after the operator
            SFWorkingLine workingLine = new SFWorkingLine(1, "a = xyz + 5;", false, saObjects);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "a = this.xyz + 5;", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            // run code
            target.SA1101_PrefixLocalCallsWithThis(ref workingLines);
            // asserts
            Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
        }

        /// <summary>
        /// A test for 	SA1115_ParameterMustFollowComma
        /// </summary>
        [TestMethod()]
        public void SA1115_ParameterMustFollowCommaTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1115";
            saObjects.Add(saObject);
            List<SAObject> noViolations = new List<SAObject>();
            //Case 1 - only some parameters are on new lines
            SFWorkingLine workingLine = new SFWorkingLine(1, "  B(p1,p2).A(p1,p2,p4,p3  //Testing, Something", false, saObjects);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "  B(p1,p2).A(p1,", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "  p2,", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "  p4,", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "  p3  //Testing, Something", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);

            //Case 2 - blank lines between parameters

            workingLine = new SFWorkingLine(1, "    public string JoinName(", false, noViolations);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(2, "    string first,", false, noViolations);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(3, "    ", false, noViolations);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(4, "    string second, string last)", false, saObjects);
            workingLines.Add(workingLine);
            workingLineExpected = new SFWorkingLine(1, "    public string JoinName(", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(2, "    string first,", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(3, "    string second,", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(4, "    string last)", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);

            // run code
            target.SA1115_ParameterMustFollowComma(ref workingLines);
            // asserts
            Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
            Assert.AreEqual(workingLinesExpected[1].Line, workingLines[1].Line);
            Assert.AreEqual(workingLinesExpected[2].Line, workingLines[2].Line);
            Assert.AreEqual(workingLinesExpected[3].Line, workingLines[3].Line);
            Assert.AreEqual(workingLinesExpected[4].Line, workingLines[4].Line);
            Assert.AreEqual(workingLinesExpected[5].Line, workingLines[5].Line);
        }

        /// <summary>
        ///A test for SA1116_SplitParametersMustStartOnLineAfterDeclaration
        ///</summary>
        [TestMethod()]
        public void SA1116_SplitParametersMustStartOnLineAfterDeclarationTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            List<SAObject> noViolations = new List<SAObject>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1116";
            saObjects.Add(saObject);
            // no space before and after the operator
            SFWorkingLine workingLine = new SFWorkingLine(1, "public string JoinName(string first,", false, saObjects);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(2, "                        String.Format(\"Test Example({0}) too broken for this test\",", false, saObjects);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(3, "                          test));", false, noViolations);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "public string JoinName(", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "    string first,", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "                        String.Format(", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "                            \"Test Example({0}) too broken for this test\",", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(1, "                          test));", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            // run code
            target.SA1116_SplitParametersMustStartOnLineAfterDeclaration(ref workingLines);
            // asserts
            Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
            Assert.AreEqual(workingLinesExpected[1].Line, workingLines[1].Line);
            Assert.AreEqual(workingLinesExpected[2].Line, workingLines[2].Line);
            Assert.AreEqual(workingLinesExpected[3].Line, workingLines[3].Line);
            Assert.AreEqual(workingLinesExpected[4].Line, workingLines[4].Line);
        }

        /// <summary>
        ///A test for SA1119_StatementMustNotUseUnnecessaryParenthesis
        ///</summary>
        [TestMethod()]
        public void SA1119_StatementMustNotUseUnnecessaryParenthesisTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1119";
            saObject.Column = 37;
            saObjects.Add(saObject);
            SAObject violation = new SAObject("SA1119", 0, 31, "", false);
            saObjects.Add(violation);

            // no space before and after the operator
            SFWorkingLine workingLine = new SFWorkingLine(1, "                    App app = ((App)(App.Current));", false, saObjects);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "                    App app = (App)App.Current;", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            // run code
            target.SA1119_StatementMustNotUseUnnecessaryParenthesis(ref workingLines);
            // asserts
            Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
        }

        /// <summary>
        ///A test for SA1120_CommentsMustContainText
        ///</summary>
        [TestMethod()]
        public void SA1120_CommentsMustContainTextTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1120";
            saObjects.Add(saObject);
            // no space before and after the operator
            SFWorkingLine workingLine = new SFWorkingLine(1, "abc //", false, saObjects);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(2, "//test", false, saObjects);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(3, "example[ /**/ empty()]", false, saObjects);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(4, "//test2", false, saObjects);
            workingLines.Add(workingLine);
            workingLine = new SFWorkingLine(5, "//", false, saObjects);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "abc ", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(2, "//test", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(3, "example[  empty()]", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            workingLineExpected = new SFWorkingLine(4, "//test2", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);            // run code
            workingLineExpected = new SFWorkingLine(5, "", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);            // run code
            target.SA1120_CommentsMustContainText(ref workingLines);
            // asserts
            Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
            Assert.AreEqual(workingLinesExpected[1].Line, workingLines[1].Line);
            Assert.AreEqual(workingLinesExpected[2].Line, workingLines[2].Line);
            Assert.AreEqual(workingLinesExpected[3].Line, workingLines[3].Line);
        }

        /// <summary>
        ///A test for SA1121_UsingDirectivesMustBePlacedWithinNamespace
        ///</summary>
        [TestMethod()]
        public void SA1121_UseBuiltInTypeAliasTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1121";
            saObject.Description = "You must use 'int' instead of...";
            saObjects.Add(saObject);
            // no space before and after the operator
            SFWorkingLine workingLine = new SFWorkingLine(1, "System.Int32 i = 50;", false, saObjects);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "int i = 50;", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            // run code
            target.SA1121_UseBuiltInTypeAlias(ref workingLines);
            // asserts
            Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
        }

        /// <summary>
        ///A test for SA1126_PrefixCallsCorrectly
        ///</summary>
        [TestMethod()]
        public void SA1126_PrefixCallsCorrectlyTest()
        {
            List<SFWorkingLine> workingLines = new List<SFWorkingLine>();
            saObjects = new List<SAObject>();
            saObject.ErrorId = "SA1126";
            saObject.Description = "The call to xyz must...";
            saObject.Column = 5;
            saObjects.Add(saObject);
            // no space before and after the operator
            SFWorkingLine workingLine = new SFWorkingLine(1, "a = xyz + 5;", false, saObjects);
            workingLines.Add(workingLine);
            List<SFWorkingLine> workingLinesExpected = new List<SFWorkingLine>();
            SFWorkingLine workingLineExpected = new SFWorkingLine(1, "a = this.xyz + 5;", false, saObjects);
            workingLinesExpected.Add(workingLineExpected);
            // run code
            target.SA1126_PrefixCallsCorrectly(ref workingLines);
            // asserts
           // Assert.AreEqual(workingLinesExpected[0].Line, workingLines[0].Line);
            Assert.Inconclusive();
        }

    }
}
